package com.zeny.express.framework.mq.ibmmq;

import java.util.Hashtable;

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool.Config;

import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.zeny.express.framework.mq.AbstractMqPool;

/**
 * refer to : redis.clients.jedis.JedisPool
 */
public class IBMMqPool extends AbstractMqPool {

	private String queueManagerName;
	private String queueName;
	
    public IBMMqPool( Config poolConfig, String queueManagerName, Hashtable<String, Object> properties,
                     String queueName) {
        super(poolConfig, new MqFactory(queueManagerName, properties, queueName));
        
        this.queueManagerName = queueManagerName;
        this.queueName = queueName;
    }

    public String getQueueManagerName() {
		return queueManagerName;
	}

	public String getQueueName() {
		return queueName;
	}

	public void returnBrokenResource(final MQQueue resource) {
    	returnBrokenResourceObject(resource);
    }
    
    public void returnResource(final MQQueue resource) {
    	returnResourceObject(resource);
    }
    
    private static class MqFactory extends BasePoolableObjectFactory {

    	private String queueManagerName;
    	private Hashtable<String, Object> properties;
    	private String queueName;

    	private int queueOpenOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT;

        public MqFactory( String queueManagerName,  Hashtable<String, Object> properties,
                 String queueName) {
            super();

            this.queueManagerName = queueManagerName;
            this.properties = properties;
            this.queueName = queueName;
    		
    		if(properties.get("port") != null)
    		{
    			String strPort = (String)properties.get("port");
    			Integer port = new Integer(strPort);
    			properties.put("port", port);
    		}
    		
    		if(properties.get("CCSID") != null)
    		{
    			String strCCSID = (String)properties.get("CCSID");
    			Integer CCSID = new Integer(strCCSID);
    			properties.put("CCSID", CCSID);
    		}
    		
    		MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
    		properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);
        }

        public Object makeObject() throws Exception {
        	MQQueueManager queueManager = new MQQueueManager(queueManagerName, properties);
        	MQQueue queue = queueManager.accessQueue(queueName, queueOpenOptions);
            
            return queue;
        }

        public void destroyObject(final Object obj) throws Exception {
            if (obj instanceof MQQueue) {
                final MQQueue queue = (MQQueue) obj;
                if (queue.isOpen()) {
                    try {
                        try {
                        	queue.close();
                        } catch (Exception e) {
                        }
                        queue.getConnectionReference().disconnect();
                    } catch (Exception e) {

                    }
                }
            }
        }

        //TODO:队列状态校验
        public boolean validateObject(final Object obj) {
            if (obj instanceof MQQueue) {
                final MQQueue queue = (MQQueue) obj;
                try {
                    return queue.isOpen();
                } catch (final Exception e) {
                    return false;
                }
            } else {
                return false;
            }
        }
    }
}
